package com.wsh.crawler.service.impl.parser;


import com.github.xiaoymin.knife4j.core.util.CollectionUtils;
import com.wsh.crawler.constant.LanguageEnum;
import com.wsh.crawler.constant.NewsSourceEnum;
import com.wsh.crawler.entity.News;
import org.jsoup.nodes.Document;
import org.jsoup.nodes.Element;
import org.jsoup.select.Elements;
import org.slf4j.Logger;
import org.slf4j.LoggerFactory;

import java.util.ArrayList;
import java.util.Date;
import java.util.List;
import java.util.stream.Collectors;

public class LaLigaParser extends AbstractNewsParser {

    private final static Logger LOGGER = LoggerFactory.getLogger(LaLigaParser.class);

    // 西甲官方图片域名
    private final static String LA_LIGA_IMAGE_DOMAIN = "https://assets.laliga.com/assets";


    public LaLigaParser() {
        super(NewsSourceEnum.LA_LIGA.getName());
    }

    @Override
    public List<String> parseArticleLinks(Document doc) {
        LOGGER.info("【西甲解析】开始解析新闻链接");

        List<String> links = new ArrayList<>();

        try {
            // 西甲官网可能的新闻链接选择器
            String[] selectors = {
                    "a[href*='/en-GB/news/']",           // 英文新闻链接
                    "a[href*='/news/']",                 // 通用新闻链接
                    "a[data-testid='news-item-link']",   // 测试ID选择器
                    ".news-list a",                      // 新闻列表链接
                    ".article-list a",                   // 文章列表链接
                    ".content-item a",                   // 内容项链接
                    "a.news-card__link",                 // 新闻卡片链接
                    "a.article-card__link",              // 文章卡片链接
                    ".latest-news a",                    // 最新新闻链接
                    "a[href*='/article/']",              // 文章链接
                    "a[href*='/story/']"                 // 故事链接
            };

            for (String selector : selectors) {
                Elements newsLinks = doc.select(selector);
                LOGGER.info("【西甲解析】使用选择器 '{}' 找到 {} 个链接", selector, newsLinks.size());

                for (Element link : newsLinks) {
                    String href = link.attr("href");
                    if (!href.isEmpty()) {
                        String fullUrl = buildFullUrl(href);

                        if (isNewsUrl(fullUrl)) {
                            links.add(fullUrl);

                            String title = extractLinkTitle(link);
                            LOGGER.info("【西甲解析】新闻：{} -> {}", title, fullUrl);
                        }
                    }
                }
            }

            // 如果没找到新闻链接，输出调试信息
            if (links.isEmpty()) {
                debugPageLinks(doc);
            }

            LOGGER.info("【西甲解析】共解析到 {} 个新闻链接", links.size());

        } catch (Exception e) {
            LOGGER.error("【西甲解析】解析新闻链接失败", e);
        }

        return links.stream().distinct().collect(Collectors.toList());
    }

    @Override
    public News parseArticle(Document doc, String url) {
        LOGGER.info("【西甲解析】正在解析{}的文章", url);

        News article = new News();
        article.setSource(NewsSourceEnum.LA_LIGA.getName());
        article.setOriginalUrl(url);
        article.setCrawlTime(new Date());

        try {
            // 解析标题
            parseTitle(doc, article);

            // 解析内容
            parseContent(doc, article);

            // 提取图片和视频
            article.setImageUrls(extractImageUrls(doc));
            article.setVideoUrls(extractVideoUrls(doc));
            article.setLanguage(LanguageEnum.EN.getValue());

            // 提取封面图片
            article.setCoverUrl(extractCoverImage(doc, article.getImageUrls()));

            LOGGER.info("【西甲解析】文章解析完成：{}", article.getTitle());

        } catch (Exception e) {
            LOGGER.error("【西甲解析】解析文章内容失败：{}", url, e);
            return null;
        }

        return article;
    }

    /**
     * 解析文章标题
     */
    private void parseTitle(Document doc, News article) {
        String[] titleSelectors = {
                "h1.headline__title",
                "h1.article-title",
                "h1.page-title",
                ".article-header h1",
                ".content-header h1",
                "h1",
                ".title",
                ".article__title"
        };

        for (String selector : titleSelectors) {
            Element titleElement = doc.selectFirst(selector);
            if (titleElement != null) {
                String title = titleElement.text().trim();
                if (!title.isEmpty()) {
                    String internationalAudiovisualRights = title.replace("""
                            International Audiovisual rights

                            Master in mgmt, methology and Football Analytics

                            Master's Degree in Sports Marketing

                            """, "");
                    article.setTitle(internationalAudiovisualRights);
                    LOGGER.info("【西甲解析】提取标题成功：{}", internationalAudiovisualRights);
                    return;
                }
            }
        }

        LOGGER.warn("【西甲解析】未找到文章标题");
    }

    /**
     * 解析文章内容
     */
    private void parseContent(Document doc, News article) {
        String[] contentSelectors = {
                ".article__body",
                ".postArticle-content",
                ".article-content",
                ".content-body",
                ".story-body",
                ".news-content",
                "article .content",
                ".main-content",
                "[data-testid='article-content']"
        };

        for (String selector : contentSelectors) {
            Element contentElement = doc.selectFirst(selector);
            if (contentElement != null) {
                String content = contentElement.text().trim();
                if (content.length() > 50) { // 确保内容不是太短
                    article.setContent(content);
                    LOGGER.info("【西甲解析】找到内容区域：{}，内容长度：{}", selector, content.length());
                    return;
                }
            }
        }

        // 备用方法：提取所有段落
        LOGGER.warn("【西甲解析】未找到内容区域，尝试备用方法");
        StringBuilder contentBuilder = new StringBuilder();

        Elements contentElements = doc.select("p, div.text-content");
        for (Element element : contentElements) {
            String text = element.text().trim();

            // 过滤掉导航、广告等无关内容
            String className = element.className().toLowerCase();
            if (isIgnoredElement(className)) {
                continue;
            }

            if (text.length() > 30) { // 过滤太短的文本
                contentBuilder.append(text).append("\n\n");
            }
        }

        if (contentBuilder.length() > 0) {
            article.setContent(contentBuilder.toString().trim());
            LOGGER.info("【西甲解析】通过备用方法获取内容，长度：{}", article.getContent().length());
        } else {
            LOGGER.warn("【西甲解析】未能提取到文章内容");
        }
    }

    /**
     * 提取封面图片
     */
    @Override
    public String extractCoverImage(Document doc, List<String> otherImageUrls) {
        LOGGER.info("【西甲解析】开始提取封面图片");

        // 1. 优先从meta标签获取
        String coverUrl = extractCoverFromMeta(doc);
        if (isValidImageUrl(coverUrl)) {
            LOGGER.info("【西甲解析】从meta标签获取封面：{}", coverUrl);
            return coverUrl;
        }

        // 2. 从页面头部的主图获取
        String[] heroSelectors = {
                ".article-header img",
                ".hero-image img",
                ".featured-image img",
                ".main-image img",
                ".article-image img",
                ".content-header img"
        };

        for (String selector : heroSelectors) {
            Element heroImage = doc.selectFirst(selector);
            if (heroImage != null) {
                String src = heroImage.attr("abs:src");
                if (isValidImageUrl(src)) {
                    LOGGER.info("【西甲解析】从页面头部获取封面：{}", src);
                    return src;
                }
            }
        }

        // 3. 从西甲官方图片域名中选择
        if (CollectionUtils.isNotEmpty(otherImageUrls)) {
            for (String imageUrl : otherImageUrls) {
                if (imageUrl.contains(LA_LIGA_IMAGE_DOMAIN)) {
                    LOGGER.info("【西甲解析】从图片内容选一张作为封面：{}", imageUrl);
                    return imageUrl;
                }
            }

            // 4. 如果没有官方图片，选择第一张有效图片
            for (String imageUrl : otherImageUrls) {
                if (isValidImageUrl(imageUrl)) {
                    LOGGER.info("【西甲解析】选择第一张有效图片作为封面：{}", imageUrl);
                    return imageUrl;
                }
            }
        }

        LOGGER.warn("【西甲解析】未找到合适的封面图片");
        return null;
    }

    /**
     * 从meta标签提取封面图片
     */
    private String extractCoverFromMeta(Document doc) {
        String[] metaSelectors = {
                "meta[property=og:image]",
                "meta[name=twitter:image]",
                "meta[property=twitter:image]",
                "meta[name=image]",
                "meta[property=image]"
        };

        for (String selector : metaSelectors) {
            Element metaElement = doc.selectFirst(selector);
            if (metaElement != null) {
                String content = metaElement.attr("content");
                if (!content.isEmpty()) {
                    return content;
                }
            }
        }

        return null;
    }

    @Override
    protected List<String> extractImageUrls(Document doc) {
        List<String> imageUrls = new ArrayList<>();

        // 从文章内容中提取图片
        String[] imageSelectors = {
                "article img[src]",
                ".article__body img[src]",
                ".content img[src]",
                ".postArticle-content img[src]",
                "img[src]"
        };

        for (String selector : imageSelectors) {
            doc.select(selector).forEach(img -> {
                String src = img.attr("abs:src");
                if (isValidImageUrl(src) && !src.contains("placeholder") && !src.contains("loading")) {
                    imageUrls.add(src);
                }
            });
        }

        // 从srcset属性中提取高质量图片
        doc.select("img[srcset]").forEach(img -> {
            String srcset = img.attr("srcset");
            if (!srcset.isEmpty()) {
                String[] sources = srcset.split(",");
                for (String source : sources) {
                    String url = source.trim().split("\\s+")[0];
                    if (isValidImageUrl(url)) {
                        imageUrls.add(url);
                    }
                }
            }
        });

        return imageUrls.stream().distinct().collect(Collectors.toList());
    }

    @Override
    protected List<String> extractVideoUrls(Document doc) {
        List<String> videoUrls = new ArrayList<>();

        // 查找video标签
        doc.select("video source").forEach(video -> {
            String url = video.attr("abs:src");
            if (!url.isEmpty()) {
                videoUrls.add(url);
            }
        });

        // 查找iframe嵌入的视频
        String[] videoIframeSelectors = {
                "iframe[src*=youtube]",
                "iframe[src*=vimeo]",
                "iframe[src*=dailymotion]",
                "iframe[src*=laliga]",
                ".video-container iframe",
                ".video-player iframe"
        };

        for (String selector : videoIframeSelectors) {
            doc.select(selector).forEach(iframe -> {
                String url = iframe.attr("abs:src");
                if (!url.isEmpty()) {
                    videoUrls.add(url);
                }
            });
        }

        return videoUrls.stream().distinct().collect(Collectors.toList());
    }

    /**
     * 构建完整URL
     */
    private String buildFullUrl(String href) {
        if (href.startsWith("//")) {
            return "https:" + href;
        } else if (href.startsWith("/")) {
            return "https://www.laliga.com" + href;
        } else if (href.startsWith("http")) {
            return href;
        }
        return href;
    }

    /**
     * 判断是否为新闻URL
     */
    private boolean isNewsUrl(String url) {
        return url.contains("/news/") ||
                url.contains("/article/") ||
                url.contains("/story/") ||
                url.contains("/feature/") ||
                url.contains("/en-GB/");
    }

    /**
     * 提取链接标题
     */
    private String extractLinkTitle(Element link) {
        String title = link.text().trim();
        if (title.isEmpty()) {
            title = link.select(".title, .headline, h3, h4").text();
        }
        if (title.isEmpty()) {
            title = link.attr("title");
        }
        if (title.isEmpty()) {
            title = "无标题";
        }
        return title;
    }

    /**
     * 验证是否为有效的图片URL
     */
    private boolean isValidImageUrl(String url) {
        if (url == null || url.trim().isEmpty()) {
            return false;
        }

        String lowerUrl = url.toLowerCase();
        return lowerUrl.contains("jpg") || lowerUrl.contains("jpeg") ||
                lowerUrl.contains("png") || lowerUrl.contains("gif") ||
                lowerUrl.contains("webp") || lowerUrl.contains("svg") ||
                lowerUrl.startsWith("data:image/");
    }

    /**
     * 判断是否为需要忽略的元素
     */
    private boolean isIgnoredElement(String className) {
        return className.contains("nav") || className.contains("menu") ||
                className.contains("ad") || className.contains("footer") ||
                className.contains("header") || className.contains("sidebar") ||
                className.contains("cookie") || className.contains("share");
    }

    /**
     * 调试页面链接
     */
    private void debugPageLinks(Document doc) {
        LOGGER.warn("【西甲解析】未找到新闻链接，输出所有链接用于调试：");
        Elements allLinks = doc.select("a[href]");
        for (int i = 0; i < Math.min(10, allLinks.size()); i++) {
            Element link = allLinks.get(i);
            String href = link.attr("href");
            String text = link.text().trim();
            if (text.length() > 50) {
                text = text.substring(0, 50) + "...";
            }
            LOGGER.info("  链接 {}: {} -> {}", i+1, text, href);
        }
    }
}